﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.ComponentModel;
using RATSharpW7.ViewModel;
using RestSharp.Serializers;
using RATSharp.Settings;

namespace RATSharp.Model
{
    /// <summary>
    /// Model for reservation.
    /// </summary>
    [DataContract]
    [SerializeAs(Name = "reservation")]
    public class Reservation
         : INotifyPropertyChanged
    {
        /// <summary>
        /// Reservation id
        /// </summary>
        [DataMember]
        public int? id { get; set; }
        /// <summary>
        /// object id for reservation
        /// </summary>
        [DataMember]
        public int objectId { get; set; }
        /// <summary>
        /// object name for Reservation
        /// </summary>
        [DataMember]
        public string objectName { get; set; }
        /// <summary>
        /// Reservations periods collection
        /// It might be a surprise why this collection is not serialized in 
        /// runtime. Hence we are using an bidirectional connection - and the
        /// main player here is period, not reservation. We can fall very quicky into
        /// endless loop as period - reservation - all periods - period - reservation - all
        /// periods ...and so on is serialized.
        /// 
        /// So be careful using this collection. It can dissapear during the page lifecycle
        /// and you need to get it from server again.
        /// 
        /// Or, of course, it is possible to keep this data in other way. E.g. use
        /// a static repository.
        /// </summary>
        [SerializeAs(Name = "periods")]
        public List<period> periods { get; set; }
        /// <summary>
        /// Reservations owner user id
        /// </summary>
        [DataMember]
        public int userId { get; set; }
        /// <summary>
        /// Reservation owner name
        /// </summary>
        [DataMember]
        public string userName { get; set; }

        private bool periodical;

        [DataMember]
        [SerializeAs(Name = "periodical")]
        public bool Periodical
        {
            get
            {
                return periodical;
            }
            set
            {
                if (this.periodical != value)
                {
                    this.periodical = value;
                    if (!periodical)
                    {
                        PeriodCount = 1;
                    }
                    this.RaisePropertyChanged("Periodical");
                }
            }
        }

        private int periodCount;

        [DataMember]
        [SerializeAs(Name = "periodCount")]
        public int PeriodCount
        {
            get
            {
                return periodCount;
            }
            set
            {
                if (this.periodCount != value)
                {
                    if (value < 1)
                    {
                        value = 1;
                    }

                    this.periodCount = value;
                    this.RaisePropertyChanged("PeriodCount");
                }
            }
        }

        /// <summary>
        /// Default constructor
        /// </summary>
        public Reservation()
        {
            //prevents NPX
            periods = new List<period>();
        }

        /// <summary>
        /// overriden for properties visibility
        /// </summary>
        /// <returns>string representation</returns>
        public override string ToString()
        {
            return String.Format("Id: {0}, ObjectName: {1}, Owner: {2}, NumberOfPeriods: {3} ", id, objectName, userName, periods.Count);
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
